package com.ihr360.payroll.model.dto.attendance.report;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ihr360.authority.sharing.entityhandler.UserResourceHandler;
import com.ihr360.payroll.model.dto.attendance.report.embeddable.AttendanceReportFlexPartHeader;
import com.ihr360.payroll.model.dto.salary.embeddable.StaffInfoSnapshot;
import com.ihr360.payroll.model.type.AttendanceSourceType;
import com.ihr360.payroll.type.AttendanceState;
import com.ihr360.shared.entitywithlistener.NumberIdWithTimeAndCompanyId;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Index;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 实际出勤天数（天）
 * 应出勤天数（天）
 * 法定计薪天数（天）
 * 月计薪天数（天）
 * 平日加班小时-标准（小时）
 * 周末加班小时-标准（小时）
 * 节假日加班小时-标准（小时）
 * 工作日加班累计（小时）
 * 休息日加班累计（小时）
 * 节假日加班累计（小时）
 * 扣薪病假时长（小时）
 * 全薪病假时长（小时）
 * 事假时长（小时）
 * 产假时长（小时）
 * 工时调整-综合（小时）
 * 节假日加班小时-综合（小时）
 * 月工作日工时-综合（小时）
 * 季工作日工时-综合（小时）
 * 年工作日工时-综合（小时）
 * 年假时长（小时）
 * 调休时长（小时）
 * 迟到次数（次数）
 * 早退次数（次数）
 *  签到遗漏次数（次数）
 *  签退遗漏次数（次数）
 *  累计迟到分钟数（分钟）
 *  累计早退分钟数（分钟）
 *  缺勤次数（次数）
 * */
@Entity
@TypeDefs({
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
@Table(
        indexes = {@Index(name = "company_staff_index", columnList = "companyId,salaryPlanId,year,month")})
@EntityListeners(value = {UserResourceHandler.class})
public class AttendanceMonthlyReportSummary extends NumberIdWithTimeAndCompanyId<Long> {
    @Embedded
    private StaffInfoSnapshot staffInfo;
    private int year;
    private int month;
    @Column(columnDefinition = "date")
    private Date startDate;
    @Column(columnDefinition = "date")
    private Date endDate;

    @Column(columnDefinition = "text", name = "flexPart")
    @Type(type = "json")
    private AttendanceReportFlexPartHeader flexPartHeader;

    /**
     * 数据来源
     */
    @Column(length = 20)
    @Enumerated(EnumType.STRING)
    private AttendanceSourceType sourceType;

    /**
     * 描述
     */
    @Column
    private String remark;

    /**
     * 薪资方案
     */
    @Column
    private String salaryPlanName;

    /**
     * 薪资方案id
     * */
    @Column(nullable = false)
    private Long salaryPlanId;

    /**
     * 薪资周期
     */
    @Column(columnDefinition = "date")
    private Date salaryStartDate;
    @Column(columnDefinition = "date")
    private Date salaryEndDate;

    /**
     * 加班统计起始时间
     */
    @Column(columnDefinition = "date")
    private Date overTimeStartDate;

    /**
     * 加班统计截止时间
     */
    @Column(columnDefinition = "date")
    private Date overTimeEndDate;

    /**
     * 状态
     * */
    @Enumerated(EnumType.STRING)
    @Column(nullable = false, length = 40)
    private AttendanceState state = AttendanceState.DRAFT;

    @OneToMany(mappedBy = "summary", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("createdAt desc")
    private List<AttendanceMonthlyReport> attendanceMonthlyReportList = new ArrayList<>();

    @JsonIgnore
    public List<AttendanceMonthlyReport> getAttendanceMonthlyReportList() {
        return attendanceMonthlyReportList;
    }

    public void setAttendanceMonthlyReportList(List<AttendanceMonthlyReport> attendanceMonthlyReportList) {
        this.attendanceMonthlyReportList = attendanceMonthlyReportList;
    }

    public Date getOverTimeStartDate() {
        return overTimeStartDate;
    }

    public void setOverTimeStartDate(Date overTimeStartDate) {
        this.overTimeStartDate = overTimeStartDate;
    }

    public Date getOverTimeEndDate() {
        return overTimeEndDate;
    }

    public void setOverTimeEndDate(Date overTimeEndDate) {
        this.overTimeEndDate = overTimeEndDate;
    }

    public AttendanceState getState() {
        return state;
    }

    public void setState(AttendanceState state) {
        this.state = state;
    }

    public String getSalaryPlanName() {
        return salaryPlanName;
    }

    public void setSalaryPlanName(String salaryPlanName) {
        this.salaryPlanName = salaryPlanName;
    }

    public Date getSalaryStartDate() {
        return salaryStartDate;
    }

    public void setSalaryStartDate(Date salaryStartDate) {
        this.salaryStartDate = salaryStartDate;
    }

    public Date getSalaryEndDate() {
        return salaryEndDate;
    }

    public void setSalaryEndDate(Date salaryEndDate) {
        this.salaryEndDate = salaryEndDate;
    }

    public AttendanceSourceType getSourceType() {
        return sourceType;
    }

    public void setSourceType(AttendanceSourceType sourceType) {
        this.sourceType = sourceType;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public StaffInfoSnapshot getStaffInfo() {
        return staffInfo;
    }

    public void setStaffInfo(StaffInfoSnapshot staffInfo) {
        this.staffInfo = staffInfo;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public AttendanceReportFlexPartHeader getFlexPartHeader() {
        return flexPartHeader;
    }

    public void setFlexPartHeader(AttendanceReportFlexPartHeader flexPartHeader) {
        this.flexPartHeader = flexPartHeader;
    }

    public Long getSalaryPlanId() {
        return salaryPlanId;
    }

    public void setSalaryPlanId(Long salaryPlanId) {
        this.salaryPlanId = salaryPlanId;
    }
}